home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
gnu
/
smlltalk
/
smtk_11.zoo
/
mstsym.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-26
|
22KB
|
879 lines
/***********************************************************************
*
* Symbol Table module.
*
***********************************************************************/
/***********************************************************************
*
* Copyright (C) 1988, 1989, 1990 Free Software Foundation, Inc.
* Written by Steve Byrne.
*
* This file is part of GNU Smalltalk.
*
* GNU Smalltalk is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 1, or (at your option) any later
* version.
*
* GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* GNU Smalltalk; see the file COPYING. If not, write to the Free Software
* Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
***********************************************************************/
/*
* Change Log
* ============================================================================
* Author Date Change
* sbyrne 16 May 90 Changed usages of "entry" to "ent" to prevent
* collisions with C compilers which have this
* identifier as a reserved word.
*
* sbyrne 21 Apr 90 Addded byteArraySymbol.
*
* sbyrne 13 Jan 90 Added thisContextSymbol.
*
* sbyrne 19 Dec 89 Rebuilt symbol table. Used to use the main OOP table
* as a symbol table, due to issues involving initial
* bootstrapping of the system. Now using open hash
* table built of arrays and linked lists, so that no
* special precautions need be taken by the GC system or
* the image save/restore facility.
*
* sbyrne 25 Jul 89 Changed undeclareName to take a parameter that
* controls whether the frame index is decremented or
* not. It appears that each block gets its own,
* non-shared temporaries/arguments, so that if the
* block is used in a process, other blocks won't have
* strange things happening to their arguments.
*
* sbyrne 5 Jan 89 Created.
*
*/
#include "mst.h"
#include "mstsym.h"
#include "mstoop.h"
#include "mstcomp.h"
#include "mstdict.h"
#include "msttree.h"
#include <stdio.h>
#include <ctype.h>
#ifdef HAS_ALLOCA_H
#include <alloca.h>
#endif
/* if defined, use the hash algorithm given in the dragon book (see usage for
better reference. */
#define dragon_book
#define max(x, y) \
( ((x) > (y)) ? (x) : (y) )
#define isSymbol(oop) \
( !isNil(oop) && (oopClass(oop) == symbolClass) )
typedef struct {
OBJ_HEADER;
OOP nextLink;
OOP symbol;
} *SymLink;
OOP andColonSymbol, atColonPutColonSymbol, atColonSymbol,
atEndSymbol, bitAndColonSymbol, bitOrColonSymbol,
bitShiftColonSymbol, blockCopyColonSymbol, classSymbol,
divideSymbol, doColonSymbol, equalSymbol,
greaterEqualSymbol, greaterThanSymbol,
ifFalseColonIfTrueColonSymbol, ifFalseColonSymbol,
ifTrueColonIfFalseColonSymbol, ifTrueColonSymbol,
integerDivideSymbol, lessEqualSymbol, lessThanSymbol,
minusSymbol, newColonSymbol, newSymbol,
nextPutColonSymbol, nextSymbol, notEqualSymbol,
notSameObjectSymbol, orColonSymbol, plusSymbol,
remainderSymbol, sameObjectSymbol, sizeSymbol,
thisContextSymbol,
timesSymbol, valueColonSymbol,
valueColonValueColonSymbol,
valueColonValueColonValueColonSymbol,
valueWithArgumentsColonSymbol,
valueSymbol,
whileFalseColonSymbol, whileTrueColonSymbol, orSymbol,
andSymbol, superSymbol, nilSymbol, trueSymbol,
falseSymbol, selfSymbol,
doesNotUnderstandColonSymbol, unknownSymbol,
charSymbol, stringSymbol, stringOutSymbol,
symbolSymbol, intSymbol, longSymbol, doubleSymbol,
voidSymbol, variadicSymbol, cObjectSymbol,
smalltalkSymbol, symbolTable, byteArraySymbol;
#ifdef symbol_table_profiling
int adds = 0, reused = 0, reprobes = 0,
hitsOn[OOP_TABLE_SIZE];
#endif /* symbol_table_profiling */
void printString();
static SymbolEntry allocSymbolEntry();
static Symbol makeNewSymbol();
static Boolean isSameString(), isWhiteSpace();
unsigned long hashString();
static void declareName(), undeclareName(), parseVariableName();
static OOP scanName(), internCountedString();
static int instanceVariableIndex(), localVarIndex();
typedef struct SymbolListStruct *SymbolList;
struct SymbolListStruct {
OOP symbol;
int index;
SymbolList prevSymbol;
};
static SymbolList symbolList;
static int methodArguments, frameIndex, maxFrameIndex;
int getArgCount()
{
return (methodArguments);
}
int getTempCount()
{
return (maxFrameIndex - methodArguments);
}
void initArgCount()
{
methodArguments = 0;
}
void initTempCount()
{
}
void declareArguments(args)
TreeNode args;
{
symbolList = nil;
frameIndex = 0;
maxFrameIndex = 0;
if (args->nodeType == unaryExprType) {
return;
} else if (args->nodeType == binaryExprType) {
declareName(args->vExpr.expression->vList.name);
methodArguments++;
} else {
for(args = args->vExpr.expression; args != nil; args = args->vList.next) {
declareName(args->vList.value->vList.name);
methodArguments++;
}
}
}
void declareTemporaries(temps)
TreeNode temps;
{
for( ; temps != nil; temps = temps->vList.next) {
declareName(temps->vList.name);
}
}
void declareBlockArguments(args)
TreeNode args;
{
for( ; args != nil; args = args->vList.next) {
declareName(args->vList.name);
}
}
static void declareName(name)
char *name;
{
SymbolList newList;
newList = (SymbolList)malloc(sizeof(struct SymbolListStruct));
newList->symbol = internString(name);
newList->index = frameIndex++;
maxFrameIndex = max(maxFrameIndex, frameIndex);
newList->prevSymbol = symbolList;
symbolList = newList;
}
void undeclareArguments(args)
TreeNode args;
{
if (args == nil) {
return;
}
if (args->nodeType == unaryExprType) {
return;
} else if (args->nodeType == binaryExprType) {
undeclareName(true);
} else {
for(args = args->vExpr.expression; args != nil; args = args->vList.next) {
undeclareName(true);
}
}
}
void undeclareTemporaries(temps)
TreeNode temps;
{
for( ; temps != nil; temps = temps->vList.next) {
undeclareName(true);
}
}
void undeclareBlockArguments(args)
TreeNode args;
{
if (args == nil) {
return;
}
for( ; args != nil; args = args->vList.next) {
undeclareName(false);
}
}
static void undeclareName(decrFrameIndex)
Boolean decrFrameIndex;
{
SymbolList oldList;
oldList = symbolList;
symbolList = symbolList->prevSymbol;
free(oldList);
if (decrFrameIndex) {
frameIndex--;
}
}
OOP findClassVariable(varName)
OOP varName;
{
OOP classOOP, assocOOP, classVariableOOP;
if (oopClass(thisClass) == behaviorClass
|| oopClass(thisClass) == classDescriptionClass) {
/* classDescriptions and above don't have class or pool variables */
/* ### this isn't quite the right test; we probably should be testing
for if we have a classClass or some derivative of that */
return (nilOOP);
}
for (classOOP = thisClass; !isNil(classOOP);
classOOP = superClass(classOOP)) {
if (oopClass(classOOP) == metaclassClass) {
/* pretend that metaclasses have the class variables and shared
pools that their instance classes do */
classVariableOOP = metaclassInstance(classOOP);
} else {
classVariableOOP = classOOP;
}
assocOOP =
dictionaryAssociationAt(classVariableDictionary(classVariableOOP),
varName);
if (!isNil(assocOOP)) {
return (assocOOP);
}
assocOOP = findSharedPoolVariable(classVariableOOP, varName);
if (!isNil(assocOOP)) {
return (assocOOP);
}
}
return (nilOOP);
}
SymbolEntry findVariable(varName)
char *varName;
{
OOP varAssoc, symbol;
int index;
symbol = internString(varName);
index = localVarIndex(symbol);
if (index >= 0) {
return (allocSymbolEntry(tempora